#pragma once
#include "types.h"

// On-disk file system format.
// Both the kernel and user programs use this header file.

#define ROOTINO  1   // root i-number
#define BSIZE 1024  // block size

#define FSMAGIC 0x10203040

// +----------+------------------>  direct (7 * 1)
// |          +--+--------------->  singly-indirect (4 * 256)
// |          |  +-+------------->  doubly-indirect (2 * 256 * 256)
// +----------+--+-+
//      7      4  2
#define NDIRECT    7
#define NINDIRECT  (BSIZE / sizeof(uint))
#define ND_INDIRECT NINDIRECT * NINDIRECT
#define MAXFILE    (NDIRECT + 4 * NINDIRECT + 2 * ND_INDIRECT)

// Directory is a file containing a sequence of dirent structures.
#define DIRSIZ 14

struct dirent {
  u16 inum;
  char name[DIRSIZ];
};

// stat
#define T_DIR     1   // Directory
#define T_FILE    2   // File
#define T_DEVICE  3   // Device
#define T_SYMLINK 4   // Symlink

struct stat {
  u32 dev;     // File system's disk device
  u32 ino;     // Inode number
  u16 type;    // Type of file
  u16 nlink;   // Number of links to file
  u32 size;    // Size of file in bytes
};

// fcntl
#define O_RDONLY    0x001
#define O_WRONLY    0x002
#define O_RDWR      0x003
#define O_NOFOLLOW  0x100
#define O_CREATE    0x200
#define O_TRUNC     0x400
#define O_APPEND    0x800

typedef enum {
  SEEK_SET,   // Seek from beginning of file
  SEEK_CUR,   // Seek from current position
  SEEK_END    // Seek from end of file
} whence_t;
